using GroupSix.Domain.Entity.App;
using GroupSix.Domain.Repositories;
using GroupSix.Domain.Services;
using GroupSix.Domain.Events;
using GroupSix.Domain.ValueObjects;
using GroupSix.Application.Dtos;

namespace GroupSix.Application.Services;

public class UserService
{
    private readonly IUserRepository _userRepository;
    private readonly IRoleRepository _roleRepository;
    private readonly ITokenService _tokenService;
    private readonly IPasswordHasher _passwordHasher;
    private readonly IDomainEventDispatcher _eventDispatcher;
    private readonly PermissionService _permissionService;

    public UserService(
        IUserRepository userRepository,
        IRoleRepository roleRepository,
        ITokenService tokenService,
        IPasswordHasher passwordHasher,
        IDomainEventDispatcher eventDispatcher,
        PermissionService permissionService)
    {
        _userRepository = userRepository;
        _roleRepository = roleRepository;
        _tokenService = tokenService;
        _passwordHasher = passwordHasher;
        _eventDispatcher = eventDispatcher;
        _permissionService = permissionService;
    }

    /// <summary>
    /// 用户注册
    /// </summary>
    /// <param name="request">注册请求</param>
    /// <returns>注册结果</returns>
    public async Task<UserRegisterResponseDto> RegisterAsync(UserRegisterRequestDto request)
    {
        // 验证输入
        if (string.IsNullOrWhiteSpace(request.Username) || 
            string.IsNullOrWhiteSpace(request.Password) || 
            string.IsNullOrWhiteSpace(request.Email))
        {
            throw new ArgumentException("账号、密码和邮箱不能为空");
        }

        // 检查账号唯一性
        if (await _userRepository.IsUsernameExistsAsync(request.Username))
        {
            throw new InvalidOperationException("账号已存在");
        }

        // 检查邮箱唯一性
        if (await _userRepository.IsEmailExistsAsync(request.Email))
        {
            throw new InvalidOperationException("邮箱已被注册");
        }

        // 验证密码强度
        if (!IsPasswordStrong(request.Password))
        {
            throw new ArgumentException("密码强度不符合要求，必须至少6位");
        }

        // 验证邮箱格式
        if (!IsValidEmail(request.Email))
        {
            throw new ArgumentException("邮箱格式不正确");
        }

        // 生成密码哈希和盐值
        var salt = _passwordHasher.GenerateSalt();
        var passwordHash = _passwordHasher.HashPassword(request.Password, salt);

        // 创建用户实体
        var user = new GsUser(
            username: request.Username,
            passwordHash: passwordHash,
            salt: salt,
            email: request.Email,
            phone: null,
            nickname: request.Username, // 使用账号作为昵称
            avatar: null,
            status: 1 // 默认状态为激活
        );

        // 保存用户
        await _userRepository.CreateAsync(user);

        // 分发领域事件
        await DispatchDomainEvents(user);

        // 返回注册结果
        return new UserRegisterResponseDto
        {
            UserId = user.Id,
            Username = user.Username,
            Email = user.Email,
            Nickname = user.Nickname ?? string.Empty,
            CreatedAt = user.CreatedAt,
            Message = "注册成功"
        };
    }

    public async Task<(GsUser user, string token)> LoginAsync(string username, string password, bool rememberMe)
    {
        if (string.IsNullOrWhiteSpace(username) || string.IsNullOrWhiteSpace(password))
            throw new Exception("用户名和密码不能为空");

        var user = await _userRepository.GetByUsernameAsync(username);
        if (user == null)
            throw new Exception("用户名或密码错误");

        // 使用领域逻辑进行登录验证
        var loginResult = user.TryLogin(password, _passwordHasher);
        
        if (!loginResult.IsSuccess)
        {
            // 保存用户状态变更
            await _userRepository.UpdateAsync(user);
            
            // 分发领域事件
            await DispatchDomainEvents(user);
            
            throw new Exception(loginResult.ErrorMessage);
        }

        // 保存用户状态变更
        await _userRepository.UpdateAsync(user);
        
        // 分发领域事件
        await DispatchDomainEvents(user);

        // 生成Token
        var token = await _tokenService.GenerateTokenAsync(user);

        return (user, token);
    }

    /// <summary>
    /// 获取用户个人信息
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>用户个人信息</returns>
    public async Task<UserProfileResponseDto> GetUserProfileAsync(Guid userId)
    {
        var user = await _userRepository.GetByIdAsync(userId);
        if (user == null)
        {
            throw new ArgumentException("用户不存在");
        }

        // 获取用户权限信息
        var permissionRequest = new GetUserPermissionsRequestDto { UserId = userId };
        var (permissionSuccess, _, permissionData) = await _permissionService.GetUserPermissionsAsync(permissionRequest);

        var response = new UserProfileResponseDto
        {
            Id = user.Id,
            Username = user.Username,
            Nickname = user.Nickname,
            Email = user.Email,
            Phone = user.Phone,
            Avatar = user.Avatar,
            Status = user.Status,
            CreatedAt = user.CreatedAt,
            UpdatedAt = user.UpdatedAt
        };

        // 如果成功获取权限信息，则添加到响应中
        if (permissionSuccess && permissionData != null)
        {
            response.Roles = permissionData.Roles;
            response.Permissions = permissionData.Permissions;
        }

        return response;
    }

    /// <summary>
    /// 更新用户个人信息
    /// </summary>
    /// <param name="request">更新请求</param>
    /// <returns>更新结果</returns>
    public async Task<UpdateUserProfileResponseDto> UpdateUserProfileAsync(UpdateUserProfileRequestDto request)
    {
        // 获取用户信息
        var user = await _userRepository.GetByIdAsync(request.UserId);
        if (user == null)
        {
            throw new ArgumentException("用户不存在");
        }

        // 验证邮箱唯一性（排除当前用户）
        if (!string.IsNullOrEmpty(request.Email) && request.Email != user.Email)
        {
            var existingUser = await _userRepository.GetByEmailAsync(request.Email);
            if (existingUser != null && existingUser.Id != request.UserId)
            {
                throw new InvalidOperationException("邮箱已被其他用户使用");
            }
        }

        // 验证邮箱格式
        if (!IsValidEmail(request.Email))
        {
            throw new ArgumentException("邮箱格式不正确");
        }

        // 验证电话号码格式
        if (!string.IsNullOrEmpty(request.Phone) && !IsValidPhone(request.Phone))
        {
            throw new ArgumentException("电话号码格式不正确");
        }

        // 更新用户信息
        user.UpdateContact(request.Email, request.Phone);
        user.UpdateProfile(request.Nickname, request.Avatar);

        // 保存更改
        await _userRepository.UpdateAsync(user);

        // 分发领域事件
        await DispatchDomainEvents(user);

        return new UpdateUserProfileResponseDto
        {
            UserId = user.Id,
            Username = user.Username,
            Nickname = user.Nickname,
            Email = user.Email,
            Phone = user.Phone,
            Avatar = user.Avatar,
            UpdatedAt = user.UpdatedAt,
            Message = "个人信息更新成功"
        };
    }

    /// <summary>
    /// 获取用户列表
    /// </summary>
    /// <param name="request">查询请求</param>
    /// <returns>用户列表</returns>
    public async Task<(bool success, string message, object? data)> GetUserListAsync(GetUserListRequestDto request)
    {
        try
        {
            var users = await _userRepository.GetAllAsync();
            var userList = users.ToList();
            
            // 应用搜索过滤
            if (!string.IsNullOrWhiteSpace(request.Keyword))
            {
                userList = userList.Where(u => 
                    u.Username.Contains(request.Keyword, StringComparison.OrdinalIgnoreCase) ||
                    u.Email.Contains(request.Keyword, StringComparison.OrdinalIgnoreCase) ||
                    (u.Nickname != null && u.Nickname.Contains(request.Keyword, StringComparison.OrdinalIgnoreCase))
                ).ToList();
            }

            // 应用状态过滤
            if (request.Status.HasValue)
            {
                userList = userList.Where(u => u.Status == request.Status.Value).ToList();
            }

            // 获取总数
            var total = userList.Count;

            // 应用分页
            var pageSize = request.PageSize > 0 ? request.PageSize : 20;
            var page = request.Page > 0 ? request.Page : 1;
            var skip = (page - 1) * pageSize;
            
            var pagedUsers = new List<UserListDto>();
            
            foreach (var user in userList.Skip(skip).Take(pageSize))
            {
                // 获取用户角色
                var userRoles = await _userRepository.GetUserRolesAsync(user.Id);
                var roleDtos = userRoles.Where(ur => ur.Role != null).Select(ur => new UserRoleDto
                {
                    Id = ur.Role!.Id,
                    Name = ur.Role!.Name,
                    Description = ur.Role!.Description
                }).ToList();
                
                pagedUsers.Add(new UserListDto
                {
                    Id = user.Id,
                    Username = user.Username,
                    Nickname = user.Nickname,
                    Email = user.Email,
                    Phone = user.Phone,
                    Status = user.Status,
                    CreatedAt = user.CreatedAt,
                    UpdatedAt = user.UpdatedAt,
                    Roles = roleDtos
                });
            }

            var result = new
            {
                items = pagedUsers,
                total = total,
                page = page,
                pageSize = pageSize,
                totalPages = (int)Math.Ceiling((double)total / pageSize)
            };

            return (true, "获取用户列表成功", result);
        }
        catch (Exception ex)
        {
            return (false, $"获取用户列表失败: {ex.Message}", null);
        }
    }

    /// <summary>
    /// 创建用户
    /// </summary>
    /// <param name="request">创建请求</param>
    /// <returns>创建结果</returns>
    public async Task<(bool success, string message, object? data)> CreateUserAsync(CreateUserRequestDto request)
    {
        try
        {
            // 验证输入
            if (string.IsNullOrWhiteSpace(request.Username) || 
                string.IsNullOrWhiteSpace(request.Password) || 
                string.IsNullOrWhiteSpace(request.Email))
            {
                return (false, "用户名、密码和邮箱不能为空", null);
            }

            // 检查用户名唯一性
            if (await _userRepository.IsUsernameExistsAsync(request.Username))
            {
                return (false, "用户名已存在", null);
            }

            // 检查邮箱唯一性
            if (await _userRepository.IsEmailExistsAsync(request.Email))
            {
                return (false, "邮箱已被注册", null);
            }

            // 验证密码强度
            if (!IsPasswordStrong(request.Password))
            {
                return (false, "密码强度不符合要求，必须至少6位", null);
            }

            // 验证邮箱格式
            if (!IsValidEmail(request.Email))
            {
                return (false, "邮箱格式不正确", null);
            }

            // 生成密码哈希和盐值
            var salt = _passwordHasher.GenerateSalt();
            var passwordHash = _passwordHasher.HashPassword(request.Password, salt);

            // 创建用户实体
            var user = new GsUser(
                username: request.Username,
                passwordHash: passwordHash,
                salt: salt,
                email: request.Email,
                phone: request.Phone,
                nickname: request.Nickname,
                avatar: request.Avatar,
                status: request.Status
            );

            // 保存用户
            await _userRepository.CreateAsync(user);

            // 分配角色
            if (request.RoleIds != null && request.RoleIds.Any())
            {
                var userRoles = request.RoleIds.Select(roleId => new GsUserRole
                {
                    UserId = user.Id,
                    RoleId = roleId,
                    CreatedAt = DateTime.UtcNow
                }).ToList();

                await _userRepository.AssignRolesAsync(user.Id, userRoles);
            }

            // 分发领域事件
            await DispatchDomainEvents(user);

            var result = new
            {
                userId = user.Id,
                username = user.Username,
                email = user.Email,
                nickname = user.Nickname,
                createdAt = user.CreatedAt
            };

            return (true, "用户创建成功", result);
        }
        catch (Exception ex)
        {
            return (false, $"创建用户失败: {ex.Message}", null);
        }
    }

    /// <summary>
    /// 更新用户
    /// </summary>
    /// <param name="request">更新请求</param>
    /// <returns>更新结果</returns>
    public async Task<(bool success, string message, object? data)> UpdateUserAsync(UpdateUserRequestDto request)
    {
        try
        {
            var user = await _userRepository.GetByIdAsync(request.Id);
            if (user == null)
            {
                return (false, "用户不存在", null);
            }

            // 检查邮箱唯一性（排除当前用户）
            if (!string.IsNullOrWhiteSpace(request.Email) && 
                request.Email != user.Email &&
                await _userRepository.IsEmailExistsAsync(request.Email))
            {
                return (false, "邮箱已被其他用户使用", null);
            }

            // 更新用户信息
            if (!string.IsNullOrWhiteSpace(request.Nickname))
                user.UpdateNickname(request.Nickname);
            
            if (!string.IsNullOrWhiteSpace(request.Email))
                user.UpdateEmail(request.Email);
            
            if (request.Phone != null)
                user.UpdatePhone(request.Phone);
            
            if (request.Avatar != null)
                user.UpdateAvatar(request.Avatar);
            
            if (request.Status.HasValue)
                user.ChangeStatus(request.Status.Value);

            // 保存更新
            await _userRepository.UpdateAsync(user);

            // 更新角色
            if (request.RoleIds != null)
            {
                var userRoles = request.RoleIds.Select(roleId => new GsUserRole
                {
                    UserId = user.Id,
                    RoleId = roleId,
                    CreatedAt = DateTime.UtcNow
                }).ToList();

                await _userRepository.UpdateUserRolesAsync(user.Id, userRoles);
            }

            var result = new
            {
                id = user.Id,
                username = user.Username,
                nickname = user.Nickname,
                email = user.Email,
                phone = user.Phone,
                avatar = user.Avatar,
                status = user.Status,
                updatedAt = user.UpdatedAt
            };

            return (true, "用户更新成功", result);
        }
        catch (Exception ex)
        {
            return (false, $"更新用户失败: {ex.Message}", null);
        }
    }

    /// <summary>
    /// 删除用户
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>删除结果</returns>
    public async Task<(bool success, string message)> DeleteUserAsync(Guid userId)
    {
        try
        {
            var user = await _userRepository.GetByIdAsync(userId);
            if (user == null)
            {
                return (false, "用户不存在");
            }

            await _userRepository.DeleteAsync(userId);
            return (true, "用户删除成功");
        }
        catch (Exception ex)
        {
            return (false, $"删除用户失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 切换用户状态
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <param name="status">新状态</param>
    /// <returns>操作结果</returns>
    public async Task<(bool success, string message)> ToggleUserStatusAsync(Guid userId, int status)
    {
        try
        {
            var user = await _userRepository.GetByIdAsync(userId);
            if (user == null)
            {
                return (false, "用户不存在");
            }

            user.ChangeStatus(status);
            await _userRepository.UpdateAsync(user);

            var statusText = status == 1 ? "启用" : "禁用";
            return (true, $"用户{statusText}成功");
        }
        catch (Exception ex)
        {
            return (false, $"切换用户状态失败: {ex.Message}");
        }
    }

    private async Task DispatchDomainEvents(GsUser user)
    {
        var domainEvents = user.GetDomainEvents();
        foreach (var domainEvent in domainEvents)
        {
            await _eventDispatcher.DispatchAsync(domainEvent);
        }
        user.ClearDomainEvents();
    }

    /// <summary>
    /// 验证密码强度
    /// </summary>
    /// <param name="password">密码</param>
    /// <returns>是否符合强度要求</returns>
    private bool IsPasswordStrong(string password)
    {
        if (string.IsNullOrWhiteSpace(password) || password.Length < 6)
            return false;

        return true; // 简化验证，只要求至少6位
    }

    /// <summary>
    /// 验证邮箱格式
    /// </summary>
    /// <param name="email">邮箱</param>
    /// <returns>格式是否正确</returns>
    private bool IsValidEmail(string email)
    {
        try
        {
            var addr = new System.Net.Mail.MailAddress(email);
            return addr.Address == email;
        }
        catch
        {
            return false;
        }
    }

    /// <summary>
    /// 验证电话号码格式
    /// </summary>
    /// <param name="phone">电话号码</param>
    /// <returns>格式是否正确</returns>
    private bool IsValidPhone(string phone)
    {
        if (string.IsNullOrWhiteSpace(phone))
            return true;

        // 简单的电话号码格式验证
        // 支持：+86-138-1234-5678, 13812345678, (86)138-1234-5678 等格式
        var phonePattern = @"^[\+]?[0-9\s\-\(\)]+$";
        return System.Text.RegularExpressions.Regex.IsMatch(phone, phonePattern);
    }
}